<?php
namespace Base;

// +----------------------------------------------------------------------
//桥链类，
//COMPILE_{PUBLIC}_BEGIN
class Bridge
{//类定义开始
	protected $view     =  null;

	protected $action   =  null;
	//选项
	protected $options  =   array('msg_error'=>'操作出错!','msg_success'=>'操作成功!');
	//回调函数
	protected $proc=null;
	//存入输入参数
	protected $arguments=array();
	//回调返回
	protected $call_returns=array();
	
	protected $unions=array();
	public $model      =  null;
	public function __construct($action)
	{
		$this->action=$action;
		$this->view=$action->view;
	}

	public function __call($method,$args){
		$m=strtolower($method);
		if (in_array($m,array('m','d','dao'),true)){
			$this->clear_options();
			$c=count($args)>1?$args[1]:'Model';
			$this->model=is_string($args[0])?($m=='m'?M($args[0],$c):D($args[0])):$args[0];
			$this->options['dao']=$this->model->getModelName();
		}elseif (in_array($m,array('t','table'),true)){
			//$this->model->setProperty('tableSuffix','_'.$args[0]);
			//$this->model->setProperty('trueTableName',$args[0]);
			$this->clear_options();
			$this->model= new \Think\Model($args[0],null);
			$this->options['dao']=$this->model->getModelName();
		}elseif (in_array($m,array('msg'),true)){
			if (substr($args[0],0,3)=='msg'){
				$this->options[$args[0]] =   $args[1];
			}else{
				$this->options['msg_success'] =   $args[0];
				$this->options['msg_error'] =   $args[1];
			}
		}elseif(in_array($m,array('data','goto','template','sql','msg_success','msg_error','page','field','table','order','limit','having','group','cache','relation','debug'),true)){
			// 连贯操作的实现
			$this->options[$m] =   $args[0];
		}elseif(in_array($m,array('where'),true)){
			// 条件
			$this->options[$m] =   is_int($args[0]) ? array($this->model->getPk()=>intval($args[0])):$args[0];
		}elseif(in_array($m,array('process'),true)){
			// 回调函数
			$this->proc =   isset($args[0]) ?: NULL;
		}elseif(in_array($m,array('union'),true)){
			// 联合//如果传入字符串，
			$options=$this->options;
			$options['table']=$options['dao'];
			switch (strtolower($args[0])) {
				case "in"://条件
					foreach($args[1] as $key=>$values){
						foreach($values as $value){
							$options['where'][$key]=$value;
							$this->unions[]=$options;
						}
					}
					break;
				case "table":
					$options['table']=$args[1];
					$this->unions[]=$options;
					break;
				default:
				   $this->unions[]=$options;
			}
		}elseif($this->model){
			$this->call_returns[$m]=call_user_func_array(array($this->model,$method),$args);
		}
		foreach($args as $k=>$v){
			$this->arguments[$m][$k]=$v;
		}
		return $this;
	}
	protected function clear_options(){
		$this->options  =   array('msg_error'=>'添加失败!','msg_success'=>'添加成功!');
		$this->options['debug']=C('APP_DEBUG');		
		$this->proc=null;
		$this->arguments=array();
		$this->call_returns=array();
		$this->unions=array();
	}
	public function findAll($varName='list',$page=false,$para=false){
		return $this->doQuery($varName,$page,$para);
	}
	public function select($varName='list',$page=false,$para=false){
		return $this->doQuery($varName,$page,$para);
	}
	public function find($varName='data'){
		return $this->doQuery($varName,false,false,'find');
	}
	public function execute(){
		return $this->doQuery(false,false,false,'execute');
	}
	public function query($varName='list'){
		return $this->doQuery($varName,false,false,'query');
	}
	protected function doQuery($varName=false,$page=false,$para=false,$do='select'){
		if (isset($this->options['cache']) && $this->options['cache']){
			$uniqueID = $this->options['dao'].'@'.md5(serialize($this->options));
			$voList=S($uniqueID);
		} else {
			$voList = NULL;
		}
		if (!is_array($voList) && empty($voList)){
			$dao=$this->model;

			if ($page){
				$listRows	=	is_int($page)?$page:20;
				$c=max(1,intval($_GET['p']));
				if (!empty($this->options['field'])) $dao->field($this->options['field']);
				if (!empty($this->options['group'])) $dao->group($this->options['group']);
				if (!empty($this->options['where'])) $dao->where($this->options['where']);
				$count	= $dao->count();
				import("ORG.Util.Page");
				$p			=	new Page($count,$listRows);
				if ($para){
					$p->parameter=$para;
				}
				$page		=	$p->show();
				$this->options['page']=$c.','.$listRows;
				$this->assign("{$varName}_count",$count);
				$this->assign("{$varName}_page",$page);
			}
			
			if (!empty($this->options['page'])) $dao->page($this->options['page']);
			if (!empty($this->options['limit'])) $dao->limit($this->options['limit']);
			if (!empty($this->options['field'])) $dao->field($this->options['field']);
			if (!empty($this->options['group'])) $dao->group($this->options['group']);
			if (!empty($this->options['where'])) $dao->where($this->options['where']);
			if (!empty($this->options['order'])) $dao->order($this->options['order']);
			if (!empty($this->options['relation'])) $dao->relation($this->options['relation']);
			
			if (!empty($this->unions)){
				foreach($this->unions as $union){
					$dao->union($union);
				}
				
			}

			$voList	= ( ! empty($this->options['sql']))?$dao->$do($this->options['sql']):$dao->$do();

			if ( ! empty($this->options['cache']) && !$page){//暂时不支持分页数据的缓存
				$glist=S('Table_Cache');
				$glist[$dao->getModelName()][$uniqueID]=true;
				S('Table_Cache',$glist);
				if (!empty($voList)){
					S($uniqueID,$voList,$this->options['cache']);
				}else{
					S($uniqueID,array(),$this->options['cache']);
				}
			}
		}
		if (!empty($this->proc)){
			$process = $this->proc;
			$process($voList,$this->arguments['process']);
		}
		if ($varName) $this->assign($varName,$voList);
		if ($this->options['debug']) dump($data);
		//清空数据
		return $voList;
	}
	protected function assign($name,$value='')
	{
		$this->view->assign($name,$value);
	}
	protected function success($message,$gotoAction=false,$waitSecond=3,$ajax=false)
	{
		if ($gotoAction){
			$this->assign('waitSecond',$waitSecond);
			$this->assign('jumpUrl',$gotoAction);
		}
		$this->action->dispatchJump($message,1,$ajax);
	}
	protected function error($message,$gotoAction=false,$waitSecond=3,$ajax=false)
	{
		if ($gotoAction){
			$this->assign('waitSecond',$waitSecond);
			$this->assign('jumpUrl',$gotoAction);
		}
		$this->action->dispatchJump($message,0,$ajax);
	}
	protected function go($url=false)
	{
		$this->action->redirect($url);
	}
	//COMPILE_{PUBLIC}_END
	//$this->model('User')->data(array('Status'=>1))->msg('成功','失败')->add();
	//COMPILE_{ADD}_BEGIN
	public function add(){//添加多条记录
		$dao=$this->model;
		$gotoAction=$this->options['goto'];
		$data=$this->options['data'];
		$msg_success=$this->options['msg_success'];
		$msg_error=$this->options['msg_error'];
		//dump($msg_success);
		$fields=$dao->getDbFields();
		$mk=false;
		foreach($fields as $k){
			if ($_POST[$k] && is_array($_POST[$k])){
				$mk=$k;break;
			}
		}
		if ($mk){//支持一次编辑多条数据
			$fields=array_keys($_POST);
			foreach($_POST[$mk] as $k=>$v){
				$list=array();
				foreach($fields as $f){
					if (is_array($_POST[$f])) $list[$f]=$_POST[$f][$k];
				}
				if (!empty($list)){
					if (!empty($data)) $list=$data;
					$result=$dao->data=$list;
					if($result && $result = $dao->add($result)){
						$error.="添加记录$v发生错误:".$dao->getError().$dao->getLastSql().'<br />';
					}else{
						$keyList[]=$result;
					}
				}
			}
		}else{
			$list=!empty($data) ? $data : $_POST;
			$result=$dao->data=$list;
			if($result && $result = $dao->add($result)){
				$keyList=$result;
			}else{
				$error.="添加记录时发生错误:".$dao->getError().$dao->getLastSql().'<br />';
			}
		}
		if ($error && $this->debug){
			$error=$error.$dao->getLastSql();
//			throw_exception($error);
		}
		if($keyList){
			if (!$gotoAction) return $keyList;
			$this->success($msg_success,$gotoAction);
		}else{
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}
	}
	//COMPILE_{ADD}_END
	//COMPILE_{EDIT}_BEGIN
	public function edit(){
		//更新信息
		$dao=$this->model;
		$gotoAction=$this->options['goto'];
		$map=$this->options['where'];
		$data=$this->options['data'];
		$msg_success=$this->options['msg_success'];
		$msg_error=$this->options['msg_error'];
		$dataKey=$dao->getPk();
		$fields=array_keys($_POST);
		$error='';
		if (is_string($map)){
			$where['_string'] = $map;
			$map=$where;
		}
		if (is_array($_POST[$dataKey])){//支持一次编辑多条数据
			foreach($_POST[$dataKey] as $k=>$v){
				$list=array();
				foreach($fields as $f){
					if (is_array($_POST[$f])) $list[$f]=$_POST[$f][$k];
				}
				if (!empty($list)){
					if (!empty($data)) $list=array_merge($list,$data);
					$list=$dao->create($list);
					if (empty( $map )){
						$map[$dataKey]=$v;
					}
					unset($list[$dataKey]);
					$dao->where($map)->save($list);
					if ($dao->getError()) $error.="更新记录$v发生错误:".$dao->getError().'<br />';
				}
			}
		}else{
			$v=$_POST[$dataKey];
			if (empty($v)){
				if (!$gotoAction) return false;
				$this->error($msg_error);
			}else{
				$list=!empty($data)?array_merge($_POST,$data):$_POST;
				$list=$dao->create($list);
				if (empty( $map )) {
					$map[$dataKey] = $v;
				}
				unset($list[$dataKey]);
				$dao->where($map)->save($list);
				if ($dao->getError()) $error.="更新记录$v发生错误:".$dao->getError().'<br />';
			}
		}
		if ($error && $this->debug){
			$error=$error.$dao->getLastSql();
			throw_exception($error);
		}
		if($error){
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}else{
			if (!$gotoAction) return true;
			$this->success($msg_success,$gotoAction);

		}
	}
	//COMPILE_{EDIT}_END
	//COMPILE_{DELETE}_BEGIN
	public function delete($varKey=false){
		$dao=$this->model;
		$gotoAction=$this->options['goto'];
		$relation=$this->options['relation'];
		$map=$this->options['where'];
		$msg_success=$this->options['msg_success'];
		$msg_error=$this->options['msg_error'];
		$dataKey=$dao->getPk();
		$varKey=$varKey?$varKey:$dataKey;
		$dataId=intval($_REQUEST[$varKey]);
		if (is_string($map)){
			$where['_string'] = $map;
			$map=$where;
		}
		if( empty( $map ) )
		{
			if ($dataId!=0) $map[$dataKey]=is_array($dataId)?array('in',$dataId):$dataId;
		}
		if(empty($map)){
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}
		if ($relation) $dao=$dao->relation($relation);
		$result =	$dao->where($map)->delete();

		if($result!==false){
			if (!$gotoAction) return true;
			$this->success($msg_success,$gotoAction);
		}else{
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}
	}
	//COMPILE_{DELETE}_END
	//COMPILE_{UPDATE}_BEGIN
	public function update($field,$value,$varKey=false){
		$dao=$this->model;
		$gotoAction=$this->options['goto'];
		$map=$this->options['where'];
		$msg_success=$this->options['msg_success'];
		$msg_error=$this->options['msg_error'];
		$dataKey=$dao->getPk();
		$varKey=$varKey?$varKey:$dataKey;
		$dataId=intval($_REQUEST[$varKey]);
		if (is_string($map)){
			$where['_string'] = $map;
			$map=$where;
		}
		if ($dataId!=0) $map[$dataKey]=is_array($dataId)?array('in',$dataId):$dataId;
		if(empty($map)){
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}

		$result=$dao->where($map)->setField($field,$value);
		if($result){
			if (!$gotoAction) return true;
			$this->success($msg_success,$gotoAction);
		}else{
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}
	}
	//COMPILE_{UPDATE}_END
	//COMPILE_{SHOW}_BEGIN
	public function show($varName='data',$varKey=false,$click=false,$nav=false){
		$dao=$this->model;
		$map=$this->options['where'];
		$relation=$this->options['relation'];
		$field=$this->options['field'];
		$msg_success=$this->options['msg_success'];
		$msg_error=$this->options['msg_error'];

		$dataKey=$dao->getPk();
		$varKey=$varKey?$varKey:$dataKey;
		$dataId=intval($_REQUEST[$varKey]);
		if (is_string($map)){
			$where['_string'] = $map;
			$map=$where;
		}
		if ($dataId!=0) $map[$dataKey]=$dataId;
		if(empty($map)){
			if (!$gotoAction) return false;
			$this->error($msg_error);
		}
		if ($relation) $dao=$dao->relation($relation);
		$data=$dao->where($map)->field($field)->find();
		if ($click)	$dao->setField($click,array('exp',"($click+1)"),$map);
		if ($this->options['debug']) dump($data);
		if ($varName) $this->assign($varName,$data);
		if ($nav && $varName){
			if (is_bool($nav)) $nav='*';
			$map[$dataKey]= array('gt',$dataId);
			$after=$dao->where($map)->field($nav)->order($dataKey.' asc')->limit('1')->find();
			$this->assign($varName.'_after',$after);
			$map[$dataKey]= array('lt',$dataId);
			$front=$dao->where($map)->field($nav)->order($dataKey.' desc')->limit('1')->find();
			$this->assign($varName.'_front',$front);
		}
		return $data;
	}
	//COMPILE_{SHOW}_END
	public function tree($varName='tree',$keyId=0){
		$list=$this->select(false);
		$tpl=$this->options['template']?$this->options['template']:"<option value=\$id \$selected>\$spacer\$name</option>";
		import('Tree');
		$tree=new Tree($list);
		$this->assign($varName,$tree->get_tree(0,$tpl,$keyId));
		return $list;
	}
	public function path($varName='path',$root=''){
		$data=$this->find(false);
		$tpl=$this->options['template']?$this->options['template']:'<a href="'.__URL__.'/view_{$id}">{$name}</a>';
		import('Tree');
		$path=$root.Tree::getPath($this->options['dao'],$data,$tpl);
		$this->assign($varName,$path);
		return $data;
	}
//COMPILE_{PUBLIC}_BEGIN
}//类定义结束
//COMPILE_{PUBLIC}_END
?>